package org.komarichin.google.blogger.dao;

import com.google.gdata.client.Query;
import com.google.gdata.client.blogger.BloggerService;
import com.google.gdata.data.*;
import com.google.gdata.data.blogger.*;
import com.google.gdata.util.ServiceException;
import org.komarichin.beans.IBlog;
import org.komarichin.beans.IComment;
import org.komarichin.beans.ILanguage;
import org.komarichin.beans.IPost;
import org.komarichin.beans.dao.IBloggerDAO;
import org.komarichin.google.blogger.Blog;
import org.komarichin.google.blogger.Post;
import org.komarichin.jdo.persistence.Comment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 * User: Mykhaylo Komarichyn
 * Date: 11.02.2010
 * Time: 10:14:14
 */
public class BloggerDAO implements IBloggerDAO<String> {

    private static final Logger log = LoggerFactory.getLogger(BloggerDAO.class);
    @Autowired
    private BloggerService googleBlogService;

    private String confFeedUrl;
    private String confFeedUriBase;
    private String confFeedUriPostsSuffix;
    private String confFeedUriCommentSuffix;
    private String googleLogin;
    private String googlePassword;

    /**
     * Parses the metafeed to get the blog ID for the authenticated user's default
     * blog.
     *

     * @return A String representation of the blog's ID.
     */
//    @Override
    public String getBlogId() {
        // Get the metafeed
        URL feedUrl;
        try {
            googleBlogService.setUserCredentials(googleLogin, googlePassword);
            feedUrl = new URL(confFeedUrl);
            Feed resultFeed = googleBlogService.getFeed(feedUrl, Feed.class);
            // If the user has a blog then return the id (which comes after 'blog-')
            if (resultFeed.getEntries().size() > 0) {
                Entry entry = resultFeed.getEntries().get(0);
                return entry.getId().split("blog-")[1];
            }
        } catch (MalformedURLException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }


    @Override
    public void createComment(IComment comment, String postId) {

        // wrap comment entry for google service
        CommentEntry myEntry = new CommentEntry();
        myEntry.setCanEdit(true);
        myEntry.setContent(new HtmlTextConstruct(comment.getContent()));
        myEntry.setUpdated(new DateTime(comment.getCreate(), TimeZone.getDefault()));
        Person p = new Person(comment.getUser(), null, comment.getEmail());
        myEntry.getAuthors().clear();
        myEntry.getAuthors().add(p);

        try {
            URL postUrl = new URL(confFeedUriBase + "/" + getBlogId() + "/" + postId + confFeedUriCommentSuffix);
            googleBlogService.insert(postUrl, myEntry);
        } catch (MalformedURLException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }


    }


    @Override
    public void createPost(IPost post) {

        PostEntry p = new PostEntry();
        p.setTitle(new PlainTextConstruct(post.getTitle()));
        ILanguage lang = post.getLanguage();
        p.setContent(new HtmlTextConstruct(post.getContent(), lang != null ? lang.getIsoName() : null));
        p.setDraft(post.isDraft());
        p.setUpdated(new DateTime(post.getUpdate(), TimeZone.getDefault()));

        try {
            URL postUrl = new URL(confFeedUriBase + "/" + getBlogId() + confFeedUriPostsSuffix);
            googleBlogService.insert(postUrl, p);
        } catch (MalformedURLException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }


    }

    @Override
    public IPost<String> getPost(String postId) {
        try {
            URL postUrl = new URL(confFeedUriBase + "/" + getBlogId() + confFeedUriPostsSuffix + "/" + postId);
            PostEntry entry = googleBlogService.getEntry(postUrl, PostEntry.class);

            IPost<String> p = new Post();
            p.setId(entry.getId().split("post-")[1]);
            p.setContent(((HtmlTextConstruct) ((TextContent) entry.getContent()).getContent()).getHtml());
            p.setTitle(entry.getTitle().getPlainText());
            p.setDraft(entry.isDraft());
            p.setUpdate(new Date(entry.getUpdated().getValue()));
//            p.setLanguage(entry.getContent().getLang()); //todo rule language
            p.setSelfLink(entry.getSelfLink().getHref());

            return p;
        } catch (MalformedURLException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    public Collection<IPost> getLatestPost() {
        List<IPost> posts = new ArrayList<IPost>();

        try {
            URL uri = new URL(confFeedUriBase + "/" + getBlogId() + confFeedUriPostsSuffix);
            Query query = new Query(uri);
            query.setMaxResults(5);
            BlogFeed resultFeed = googleBlogService.query(query, BlogFeed.class);

            for (BlogEntry entry : resultFeed.getEntries()) {
                IPost<String> p = new Post();
                p.setContent(((HtmlTextConstruct) ((TextContent) entry.getContent()).getContent()).getHtml());
                p.setTitle(entry.getTitle().getPlainText());
                p.setDraft(entry.isDraft());
//                p.setLanguage(entry.getContent().getLang());
                p.setSelfLink(entry.getSelfLink().getHref());
                p.setId(entry.getId().split("post-")[1]);
                p.setUpdate(new Date(entry.getUpdated().getValue()));
                posts.add(p);
            }
            return posts;
        } catch (MalformedURLException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }


    @Override
    public Collection<IComment> getComments(String postId) {
        List<IComment> comments = new ArrayList<IComment>();
        try {
            URL feedUrl = new URL(confFeedUriBase + "/" + getBlogId() + "/" + postId + confFeedUriCommentSuffix);
            BlogCommentFeed resultFeed = googleBlogService.getFeed(feedUrl, BlogCommentFeed.class);
            for (CommentEntry comment : resultFeed.getEntries()) {
                IComment c = new Comment();
                c.setContent(((HtmlTextConstruct) ((TextContent) comment.getContent()).getContent()).getHtml());
                c.setCreate(new Date(comment.getUpdated().getValue()));
                comments.add(c);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        }
        return comments;
    }

    @Override
    public IBlog getBlog() {
        try {
            final URL feedUrl = new URL(confFeedUrl);
            Feed resultFeed = googleBlogService.getFeed(feedUrl, Feed.class);

            if (resultFeed.getEntries().size() > 0) {
                Entry entry = resultFeed.getEntries().get(0);
                IBlog<String> b = new Blog();
                b.setId(entry.getId());
                b.setTitle(entry.getTitle().getPlainText());
                return b;
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public Collection<IPost> getPosts() {

        List<IPost> posts = new ArrayList<IPost>();

        try {
            URL feedUrl = new URL(confFeedUriBase + "/" + getBlogId() + confFeedUriPostsSuffix);
            BlogFeed resultFeed = googleBlogService.getFeed(feedUrl, BlogFeed.class);
            for (BlogEntry entry : resultFeed.getEntries()) {
                IPost<String> p = new Post();
                p.setContent(((HtmlTextConstruct) ((TextContent) entry.getContent()).getContent()).getHtml());
                p.setTitle(entry.getTitle().getPlainText());
                p.setDraft(entry.isDraft());
//            p.setLanguage(entry.getContent().getLang());
                p.setSelfLink(entry.getSelfLink().getHref());
                p.setId(entry.getId().split("post-")[1]);
                posts.add(p);
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        } catch (ServiceException e) {
            log.error(e.getMessage(), e);
        }

        return posts;
    }

    public void setConfFeedUrl(String confFeedUrl) {
        this.confFeedUrl = confFeedUrl;
    }

    public void setConfFeedUriPostsSuffix(String confFeedUriPostSuffix) {
        this.confFeedUriPostsSuffix = confFeedUriPostSuffix;
    }


    public void setConfFeedUriCommentSuffix(String confFeedUriCommentSuffix) {
        this.confFeedUriCommentSuffix = confFeedUriCommentSuffix;
    }

    public void setConfFeedUriBase(String confFeedUriBase) {
        this.confFeedUriBase = confFeedUriBase;
    }

    public void setGoogleLogin(String googleLogin) {
        this.googleLogin = googleLogin;
    }

    public void setGooglePassword(String googlePassword) {
        this.googlePassword = googlePassword;
    }


}
